package br.com.vti.leilao.view.bean;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;

import br.com.vti.leilao.model.business.Business;
import br.com.vti.leilao.model.business.exception.ApplicationException;
import br.com.vti.leilao.model.entity.Usuario;
import br.com.vti.leilao.view.util.EmailUtil;
import br.com.vti.leilao.view.util.EmailUtilException;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.userdetails.UserDetailsService;

@ManagedBean
@ViewScoped
public class UsuarioBean extends CommonBean<Usuario, ApplicationException> {

    private static final long serialVersionUID = 7053723507220511445L;
    
    private String codigoAtivacao;
    private String senhaConf;
    private String senhaAnt;
    private boolean ativo;
    
    @ManagedProperty("#{usuarioBusiness}")
    private Business<Usuario, ApplicationException> business;
    
    @ManagedProperty("#{emailUtil}")
    private EmailUtil emailUtil;

    public String getCodigoAtivacao() {
        return codigoAtivacao;
    }

    public void setCodigoAtivacao(String codigoAtivacao) {
        this.codigoAtivacao = codigoAtivacao;
    }

    public String getSenhaConf() {
        return senhaConf;
    }

    public void setSenhaConf(String senhaConf) {
        this.senhaConf = senhaConf;
    }

    public boolean isAtivo() {
        return ativo;
    }

    public void setAtivo(boolean ativo) {
        this.ativo = ativo;
    }

    /* (non-Javadoc)
     * @see br.com.vti.leilao.view.bean.Bean#getBusiness()
     */
    @Override
    public Business<Usuario, ApplicationException> getBusiness() {
        return business;
    }

    /* (non-Javadoc)
     * @see br.com.vti.leilao.view.bean.Bean#setBusiness
     */
    @Override
    public void setBusiness(Business<Usuario, ApplicationException> business) {
        this.business = business;
    }

    public EmailUtil getEmailUtil() {
        return emailUtil;
    }

    public void setEmailUtil(EmailUtil emailUtil) {
        this.emailUtil = emailUtil;
    }

    @Override
    public void limpar() {
        super.limpar();
        resetCadastro();
    }

    private void resetCadastro() {
        getEntidade().setPermissoes("ROLE_FUNCIONARIO");
        getEntidade().setStatus(new Character('I'));
        setAtivo(false);
        Usuario usuarioLogado = getJsfManager().getUsuarioLogado();
    	if (usuarioLogado != null && !usuarioLogado.getPermissoes().contains("ROLE_ADMIN")) {
            BeanUtils.copyProperties(usuarioLogado, this.getEntidade(), "senha");
            this.senhaAnt = usuarioLogado.getSenha();
        }
    }

    @Override
    public void resetCadastro(ActionEvent event) {
        super.resetCadastro(event);
        resetCadastro();
    }

    private String md5(String senha) {
        String hash = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(senha.getBytes());
            hash = new String();
            for (int i = 0; i < bytes.length; i++) {
                int parteAlta = ((bytes[i] >> 4) & 0xf) << 4;
                int parteBaixa = bytes[i] & 0xf;
                if (parteAlta == 0) {
                    hash += "0";
                }
                hash += Integer.toHexString(parteAlta | parteBaixa);
            }
        } catch (NoSuchAlgorithmException e) {
            getLogger().error(e);
        }
        return hash;
    }

    @Override
    public void salvar() {
        if (senhaConf != null && senhaConf.equals(getEntidade().getSenha())) {
            Usuario usuarioLogado = getJsfManager().getUsuarioLogado();
            if (usuarioLogado != null && usuarioLogado.getPermissoes().contains("ROLE_ADMIN")) {
                getEntidade().setStatus(isAtivo() ? 'A' : 'I');
            }
            if ("".equals(getEntidade().getSenha())) {
                getEntidade().setSenha(this.senhaAnt);
            } else {
                getEntidade().setSenha(md5(getEntidade().getSenha()));
            }
            String email = getEntidade().getEmail();
            if (!email.contains(getEntidade().getEmpresaFk().getDominio())) {
                email = getEntidade().getEmail() + "@" + getEntidade().getEmpresaFk().getDominio();
            }
            getEntidade().setEmail(email);
            try {
                if (getEntidade() != null
                        && getEntidade().getId() == null) {
                    getBusiness().inserir(getEntidade());
                    if (usuarioLogado != null && !usuarioLogado.getPermissoes().contains("ROLE_ADMIN")) {
                        getBusiness().getMessageFactory().addInfoMessage(getBusiness().getMessageFactory().getMessage("msg.usuario.salvo"));
                    } else {
                        emailUtil.enviarEmailSimples(null, email,
                                getBusiness().getMessageFactory().getMessage("texto.email.titulo"),
                                getBusiness().getMessageFactory().getMessage("texto.email.msg", gerarLink(getEntidade())));
                        getBusiness().getMessageFactory().addInfoMessage(getSuccessMsg("msg.usuario.salvo"));
                    }
                } else if (usuarioLogado != null) {
                    getBusiness().atualizar(getEntidade());
                    getBusiness().getMessageFactory().addInfoMessage(getSuccessMsg("item.atualizado"));
                }
            } catch (EmailUtilException e) {
                getLogger().error(e);
                getBusiness().getMessageFactory().addInfoMessage(getBusiness().getMessageFactory().getMessage("erro.usuario.salvo.email"));
            } catch (ApplicationException e) {
                getBusiness().getMessageFactory().addErrorMessage(e.getMessage());
            } catch (Exception e) {
                getLogger().error(e);
            }
            limpar();
        } else {
            getBusiness().getMessageFactory().addErrorMessage(getBusiness().getMessageFactory().getMessage("erro.senha.naoconfere"));
        }
    }

    private String gerarLink(Usuario usuario) {
    	StringBuilder link = new StringBuilder("");
    	String retorno = "";
        if (usuario != null) {
            try {
            	link.append(getJsfManager().getHttpRequest().getScheme());
            	link.append("://");
            	link.append(getJsfManager().getHttpRequest().getServerName());
            	link.append(":");
            	link.append(getJsfManager().getHttpRequest().getServerPort());
            	link.append(getJsfManager().getHttpRequest().getContextPath());
            	link.append("/pages/ativacao.jsf?id=");
            	link.append(usuario.getId());
            	link.append("&cod=");
            	link.append(gerarCodigo(usuario));
            	
            	URL url = new URL(link.toString());
            	
            	retorno = url.toString();
            } catch (MalformedURLException e) {
                getLogger().error(e);
            }
        }
        return retorno;
    }
    
    public void ativarCadastro() {
        if (getEntidadePesquisa().getId() != null && getEntidadePesquisa().getId() > 0 && getCodigoAtivacao() != null && !getCodigoAtivacao().isEmpty()) {
            try {
                Usuario usuario = getBusiness().getDao().procurarPorId(getEntidadePesquisa());
                if (usuario != null) {
                    String codigo = gerarCodigo(usuario);
                    if (codigo.equals(getCodigoAtivacao())) {
                        usuario.setStatus('A');
                        getBusiness().atualizar(usuario);
                        getBusiness().getMessageFactory().addInfoMessage(getBusiness().getMessageFactory().getMessage("msg.cadastro.usuario"));
                    } else {
                        getBusiness().getMessageFactory().addInfoMessage(getBusiness().getMessageFactory().getMessage("erro.codigo.invalido"));
                    }
                }
            } catch (Exception e) {
                getLogger().error(e);
                getBusiness().getMessageFactory().addInfoMessage(getBusiness().getMessageFactory().getMessage("erro.cadastro.usuario"));
            }
        }
    }
    
    public void esqueciSenha() {
        UUID uuid = UUID.randomUUID();
        String myRandom = uuid.toString();
        String novaSenha = myRandom.substring(0, 6);

        String email = getEntidadePesquisa().getEmail();
        UserDetailsService userDetails = (UserDetailsService) getBusiness();
        try {
            Usuario usuario = (Usuario) userDetails.loadUserByUsername(email);
            if (usuario != null) {
                setEntidade(usuario);
                getEntidade().setSenha(md5(novaSenha));
                getBusiness().atualizar(getEntidade());

                emailUtil.enviarEmailSimples(null, email,
                        getBusiness().getMessageFactory().getMessage("texto.email.esqueci.senha"),
                        getBusiness().getMessageFactory().getMessage("texto.email.msg.senha", novaSenha));
                getBusiness().getMessageFactory().addInfoMessage(getBusiness().getMessageFactory().getMessage("msg.esqueci.senha"));
            }
        } catch (Exception e) {
            getLogger().error(e);
            getBusiness().getMessageFactory().addErrorMessage(getBusiness().getMessageFactory().getMessage("erro.cadastro.usuario"));
        }
    }

    private String gerarCodigo(Usuario usuario) {
        return md5(usuario.getEmail() + ":" + usuario.getSenha() + "@" + usuario.getStatus());
    }
    
    public void redirecionarLogin() {
        Usuario usuarioLogado = getJsfManager().getUsuarioLogado();
        if (usuarioLogado != null && !usuarioLogado.getPermissoes().contains("ROLE_ADMIN")) {
            try {
                getJsfManager().getExternalContext().redirect(getJsfManager().getHttpRequest().getContextPath() + "/pages/leilao.jsf");
            } catch (IOException e) {
                getLogger().error(e);
            }
        }
    }

    @Override
    public void setEntidade(Usuario entidade) {
        super.setEntidade(entidade);
        if (entidade != null && entidade.getStatus() != null) {
            setAtivo(entidade.getStatus() == 'A');
        }
        this.senhaAnt = entidade.getSenha();
    }
    
    public String getLabelStatus(String status) {
        String label = "";
        if (status != null && status.equalsIgnoreCase("A")) {
            label = "ATIVO";
        } else if (status != null && status.equalsIgnoreCase("I")) {
            label = "INATIVO";
        }
        return label;
    }
    
}
